package com.woniu.gateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.woniu.gateway.common.ResultBody;
import com.woniu.gateway.config.DataFilterConfig;
import com.woniu.gateway.util.JwtUtil;
import com.woniu.gateway.util.PathUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.AbstractMap;

/**
 * @Auther: 李浪  <br/>
 * @Date: 2020/3/26:0:38  <br/>
 * @Description:
 */
@Component
@Slf4j
public class JwtAuthPreFilter extends ZuulFilter {

    @Autowired
    ObjectMapper objectMapper;

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    DataFilterConfig dataFilterConfig;

    /**
     * pre：路由之前
     * routing：路由之时
     * post： 路由之后
     * error：发送错误调用
     *
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * filterOrder：过滤的顺序 序号配置可参照 https://blog.csdn.net/u010963948/article/details/100146656
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 2;
    }

    /**
     * shouldFilter：逻辑是否要过滤
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        //路径与配置的相匹配，则执行过滤
        RequestContext ctx = RequestContext.getCurrentContext();
        for (String pathPattern : dataFilterConfig.getAuthPath()) {
            if (PathUtil.isPathMatch(pathPattern, ctx.getRequest().getRequestURI())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 执行过滤器逻辑，验证token
     *
     * @return
     */
    @Override
    public Object run() throws ZuulException {
        System.out.println("执行Pre");
        RequestContext context= RequestContext.getCurrentContext();
        context.addZuulRequestHeader("userName","hello");
        //从请求头中获取token
        String token = context.getRequest().getHeader("token");
        if(token == null || "".equals(token.trim())){
            context.setSendZuulResponse(false); //不进行路由
            context.setResponseStatusCode(403);
            context.setResponseBody("{\"code\":403,\"message\":\"token not found\"}");
        }else{
            //验证token
            try {
                Claims claims = jwtUtil.parseJWT(token);
                Integer userId = (Integer) claims.get("userId");
                context.setSendZuulResponse(true);
                context.setResponseStatusCode(HttpStatus.OK.value());
                context.setResponseBody("{\"code\":200,\"message\":\"success\"}");
                context.addZuulRequestHeader("userId",userId.toString());
                //context.addZuulResponseHeader("userId",userId.toString());
            } catch (ExpiredJwtException e) {
                e.printStackTrace();
                context.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
                context.setResponseBody("{\"code\":403,\"message\":\"token expire\"}");
            }catch (Exception e) {
                e.printStackTrace();
                context.setResponseStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
                context.setResponseBody("{\"code\":500,\"message\":\"invalid token\"}");
            }

        }

        return null;
    }


    private String toJsonString(Object o) {
        try {
            return objectMapper.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            log.error("json序列化失败", e);
            return null;
        }
    }
}
